﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.SharePoint.Client;

namespace Com.CodePlex.SPC3.ProfileImageUpload {

    public class DAOResult {
        public bool Success = false;
        public string Message;
    }

    public class SharePointDAO {

        public string SelectProfileProperty(string siteurl, string username, string password, string authtype, string accountname, string field) {
            userprofileservice.UserProfileService service = GetUserProfileService(siteurl, username, password, authtype);
            userprofileservice.PropertyData value = service.GetUserPropertyByAccountName(accountname, field);
			if (value.Values.Length == 0) {
				return null; //no property
			}
            return value.Values[0].Value.ToString();
        }

        private userprofileservice.UserProfileService GetUserProfileService(string siteurl, string username, string password, string authtype) {
            userprofileservice.UserProfileService service = new userprofileservice.UserProfileService();
            if (authtype == "TMG:BASIC") {
                service.CookieContainer = GetAuthCookies(siteurl, username, password);
            } else {
                if (string.IsNullOrEmpty(username)) {
                    service.UseDefaultCredentials = true;
                } else {
                    service.Credentials = BuildCredentials(siteurl, username, password, authtype);
                }
            }
            service.Url = siteurl.CombineUrl("/_vti_bin/userprofileservice.asmx");
            return service;
        }

        private CookieContainer GetAuthCookies(string siteurl, string username, string password) {
            Uri uri = new Uri(siteurl);
            string server = String.Format("{0}://{1}/{2}", uri.Scheme, uri.DnsSafeHost, "CookieAuth.dll?Logon");
            HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(server);
            request.Proxy = null;
            request.Method = "POST";
            request.CookieContainer = new CookieContainer();
            request.ContentType = "application/x-www-form-urlencoded";
            byte[] body = Encoding.UTF8.GetBytes(string.Format("curl=Z2F&flags=0&forcedownlevel=0&formdir=3&trusted=0&username={1}&password={2}&SubmitCreds=Log On", uri, username, password));
            request.ContentLength = body.Length;
            Stream stream = request.GetRequestStream();
            stream.Write(body, 0, body.Length);
            stream.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            CookieContainer container = new CookieContainer();
            foreach (Cookie cookie in request.CookieContainer.GetCookies(uri)) {
                container.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
            }
            foreach (Cookie cookie in response.Cookies) {
                container.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
            }
            bool found = false;
            foreach (Cookie cookie in container.GetCookies(uri)) {
                //ISAWPLB
                //WSS_KeepSessionAuthenticated
                //cadataAAB595F0AE3845DF9D5E84E0C75A5C62
                if (cookie.Name.Contains("cadata")) {
                    found = true;
                }
            }
            if (!found) {
                throw new Exception("Failed to authenticate with ISA/TMG");
            }
            return container;
        }

        //http://msdn.microsoft.com/en-us/library/ms544240.aspx
        //http://spservices.codeplex.com/wikipage?title=ModifyUserPropertyByAccountName
        public void UpdateProfileProperty(string siteurl, string username, string password, string authtype, string accountname, string field, string value) {
            userprofileservice.UserProfileService service = GetUserProfileService(siteurl, username, password, authtype);
            userprofileservice.PropertyData[] data = new userprofileservice.PropertyData[1];
            data[0] = new userprofileservice.PropertyData();
            data[0].Name = field;
            data[0].Values = new userprofileservice.ValueData[1];
            data[0].Values[0] = new userprofileservice.ValueData();
            data[0].Values[0].Value = value;
            data[0].IsValueChanged = true;
            service.ModifyUserPropertyByAccountName(accountname, data);
        }

        public string UploadDocument(string siteurl, string username, string password, string authtype, string listname, string listfolder, string name, byte[] data) {
            using (ClientContext context = new ClientContext(siteurl)) {
                context.AuthenticationMode = ClientAuthenticationMode.Default;
                if (string.IsNullOrEmpty(username)) {

                } else {
                    context.Credentials = BuildCredentials(siteurl, username, password, authtype);
                }
                List list = context.Web.Lists.GetByTitle(listname);
                context.Load(list);
                context.Load(list.RootFolder);
                context.ExecuteQuery();
                string url = siteurl.CombineUrl(list.RootFolder.ServerRelativeUrl).CombineUrl(listfolder).CombineUrl(name);
				FileCreationInformation fci = new FileCreationInformation();
				fci.Content = data;
				fci.Overwrite = true;
				fci.Url = url;
				Microsoft.SharePoint.Client.File file = list.RootFolder.Files.Add(fci);
				context.ExecuteQuery();
                return url;
            }
        }

        public DAOResult ConnectToSite(string siteurl, string username, string password, string authtype) {
            DAOResult result = new DAOResult();
            using (WebClient client = new WebClient()) {
                try {
                    if (string.IsNullOrEmpty(username)) {
                        client.UseDefaultCredentials = true;
                    } else {
                        client.Credentials = BuildCredentials(siteurl, username, password, authtype);
                    }
                    result.Message = client.DownloadString(siteurl);
                    result.Success = true;
                } catch (Exception ex) {
                    result.Message = ex.ToString();
                }
            }
            return result;
        }

        private ICredentials BuildCredentials(string siteurl, string username, string password, string authtype) {
            NetworkCredential cred;
            if (username.Contains(@"\")) {
                string domain = username.Substring(0, username.IndexOf(@"\"));
                username = username.Substring(username.IndexOf(@"\") + 1);
                cred = new System.Net.NetworkCredential(username, password, domain);
            } else {
                cred = new System.Net.NetworkCredential(username, password);
            }
            CredentialCache cache = new CredentialCache();
            if (authtype.Contains(":")) {
                authtype = authtype.Substring(authtype.IndexOf(":") + 1); //remove the TMG: prefix
            }
            cache.Add(new Uri(siteurl), authtype, cred);
            return cache;
        }
    }
}
